package com.dfs.parent.common.feign.config;

import com.dfs.parent.common.core.constant.TokenConstant;
import com.dfs.parent.common.feign.openfeign.FeignInterceptor;
import feign.Request;
import feign.RequestInterceptor;
import feign.Retryer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.concurrent.TimeUnit;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * <h1>Feign 调用时, 把 Header 也传递到服务提供方</h1>
 * */
@Slf4j
@Configuration
@LoadBalancerClients(defaultConfiguration = GrayLoadBalancerConfig.class)
@ConditionalOnClass(value = RequestInterceptor.class)
public class FeignConfig {
    /**
     * <h2>开启 OpenFeign 日志</h2>
     * NONE：默认的，不显示任何⽇志，这个级别性能最好；
     * BASIC：仅记录请求⽅法、URL、响应状态码以及执⾏时间，适用于⽣产问题追踪；
     * HEADERS：在BASIC级别的基础上，记录请求和响应的header；
     * FULL：记录请求和响应的header、body和元数据，适⽤于开发及测试环境定位问题。
     *
     * */
//    @Bean
//    public Logger.Level feignLogger() {
//        return Logger.Level.BASIC;   //  需要注意, 日志级别需要修改成 debug
//    }

    /**
     * <h2>OpenFeign 开启重试</h2>
     * period = 100 发起当前请求的时间间隔, 单位是 ms
     * maxPeriod = 1000 发起当前请求的最大时间间隔, 单位是 ms
     * maxAttempts = 1 最多请求次数
     * */
    @Bean
    public Retryer feignRetryer() {
        return new Retryer.Default(
                100,
                SECONDS.toMillis(1),
                2
        );
    }

    /**
     * TODO 结合Nacos变成动态配置。
     */

    public static final int CONNECT_TIMEOUT_MILLS = 30000;
    public static final int READ_TIMEOUT_MILLS = 6000;

    /**
     * <h2>对请求的连接和响应时间进行限制</h2>
     * */
    @Bean
    public Request.Options options() {

        return new Request.Options(
                CONNECT_TIMEOUT_MILLS, TimeUnit.MICROSECONDS,
                READ_TIMEOUT_MILLS, TimeUnit.MILLISECONDS,
                true
        );
    }

    /**
     * <h2>给 Feign 配置请求拦截器</h2>
     * RequestInterceptor 是我们提供给 open-feign 的请求拦截器, 把 Header 信息传递
     * */
    @Bean
    public RequestInterceptor headerInterceptor() {
       return new FeignInterceptor();
//        return template -> {
//            ServletRequestAttributes attributes =
//                    (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//            if (null != attributes) {
//                HttpServletRequest request = attributes.getRequest();
//                Enumeration<String> headerNames = request.getHeaderNames();
//
//                if (null != headerNames) {
//                    while (headerNames.hasMoreElements()) {
//                        String name = headerNames.nextElement();
//                        String values = request.getHeader(name);
//                        if(name.equals(TokenConstant.DFS_TOKEN)){
//                            template.header(name, values);
//                            template.header(TokenConstant.DFS_TOKEN, values);
//                        }
//               //         System.out.println("name==》"+name + "   "+values);
//                        // 不能把当前请求的 content-length 传递到下游的服务提供方, 这明显是不对的
//                        // 请求可能一直返回不了, 或者是请求响应数据被截断
////                        if (!name.equalsIgnoreCase("content-length")) {
////                            // 这里的 template 就是 RestTemplate
//                        //    template.header(name, values);
////                        }
//                    }
//                }
//            }
//        };
    }
}
